package com.jianggujin.demo.admin.handler;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Map;

import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import com.jianggujin.modulelink.config.JModuleConfig;
import com.jianggujin.modulelink.config.JModuleLoadPolicy;
import com.jianggujin.modulelink.config.JSpringBootModuleConfig;
import com.jianggujin.modulelink.config.JSpringModuleConfig;
import com.jianggujin.modulelink.magager.JModuleManager;
import com.jianggujin.modulelink.util.JStringUtils;

import fi.iki.elonen.NanoHTTPD.IHTTPSession;

public class LoadHandler extends AbstractHandler {

    private File repository = null;

    public LoadHandler() {
        String mavenHome = System.getenv("MAVEN_HOME");
        if (mavenHome == null) {
            File conf = new File(mavenHome, "conf/settings.xml");
            if (conf.exists()) {
                try {
                    Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(conf);
                    NodeList list = doc.getElementsByTagName("localRepository");
                    if (list.getLength() > 0) {
                        repository = new File(list.item(0).getTextContent());
                        return;
                    }
                } catch (Exception e) {
                }
            }
        }
        repository = new File(System.getProperty("user.home"), ".m2/repository");
    }

    @Override
    protected Object handle(JModuleManager manager, IHTTPSession session, Map<String, String> params) throws Exception {
        String moduleName = params.get("moduleName");
        if (JStringUtils.isEmpty(moduleName)) {
            return error("moduleName不能为空");
        }
        String type = params.get("type");

        if ("1".equals(type) || "2".equals(type)) {
            File moduleRoot = new File(new File(System.getProperty("user.dir")).getParent(),
                    "JModuleLink-spring-module/target/classes");
            JSpringModuleConfig moduleConfig = new JSpringModuleConfig(moduleName);
            initModuleConfig(moduleConfig, moduleRoot, params);
            if ("1".equals(type)) {
                moduleConfig.addXmlPattern("classpath:spring-beans.xml");
            } else {
                moduleConfig.addScanPackage("com.jianggujin.demo.action");
                moduleConfig.addScanPackage("com.jianggujin.demo.listener");
            }
            addSpringDependencies(moduleConfig);
            manager.load(moduleConfig);
        } else if ("3".equals(type)) {
            File moduleRoot = new File(new File(System.getProperty("user.dir")).getParent(),
                    "JModuleLink-module/target/classes");
            JModuleConfig moduleConfig = new JModuleConfig(moduleName);
            initModuleConfig(moduleConfig, moduleRoot, params);
            moduleConfig.addScanPackage("com.jianggujin.demo.action");
            moduleConfig.addScanPackage("com.jianggujin.demo.listener");
            manager.load(moduleConfig);
        } else if ("4".equals(type)) {
            File moduleRoot = new File(new File(System.getProperty("user.dir")).getParent(),
                    "JModuleLink-spring-boot-module/target/classes");
            JSpringBootModuleConfig moduleConfig = new JSpringBootModuleConfig(moduleName);
            initModuleConfig(moduleConfig, moduleRoot, params);
            moduleConfig.addSource("com.jianggujin.demo.Application");
            addSpringBootDependencies(moduleConfig);
            manager.load(moduleConfig);
        } else {
            return error("type错误");
        }
        return success(null);
    }

    private void initModuleConfig(JModuleConfig moduleConfig, File moduleRoot, Map<String, String> params)
            throws MalformedURLException {
        moduleConfig.addModuleUrl(moduleRoot.toURI().toURL());
        moduleConfig
                .setModuleLoadPolicy(JModuleLoadPolicy.valueOf(params.getOrDefault("moduleLoadPolicy", "AbortPolicy")));
        moduleConfig.setDescription(params.get("description"));
    }

    /**
     * 添加Spring依赖
     * 
     * @param moduleConfig
     * @throws IOException
     */
    private void addSpringDependencies(JModuleConfig moduleConfig) throws IOException {
        String version = "4.3.18.RELEASE";
        String[] jars = { "context", "aop", "beans", "core", "expression" };
        for (String jar : jars) {
            addDependency(moduleConfig, "org/springframework", "spring-" + jar, version);
        }
        addDependency(moduleConfig, "commons-logging", "commons-logging", "1.2");
    }

    /**
     * 添加SpringBoot依赖
     * 
     * @param moduleConfig
     * @throws IOException
     */
    private void addSpringBootDependencies(JModuleConfig moduleConfig) throws IOException {
        String version = "1.5.14.RELEASE";
        String[] jars = { "boot-starters", "boot", "boot-autoconfigure", "boot-starter-logging" };
        for (String jar : jars) {
            addDependency(moduleConfig, "org/springframework/boot", "spring-" + jar, version);
        }
        version = "4.3.18.RELEASE";
        jars = new String[] { "context", "aop", "beans", "core", "expression" };
        for (String jar : jars) {
            addDependency(moduleConfig, "org/springframework", "spring-" + jar, version);
        }
        addDependency(moduleConfig, "ch.qos.logback", "logback-classic", "1.1.11");
        addDependency(moduleConfig, "ch.qos.logback", "logback-core", "1.1.11");

        version = "1.7.25";
        jars = new String[] { "jcl-over-slf4j", "jul-to-slf4j", "log4j-over-slf4j", "slf4j-api" };
        for (String jar : jars) {
            addDependency(moduleConfig, "org.slf4j", jar, version);
        }
    }

    /**
     * 添加依赖
     * 
     * @param moduleConfig
     * @param groupId
     * @param artifactId
     * @param version
     * @throws IOException
     */
    private void addDependency(JModuleConfig moduleConfig, String groupId, String artifactId, String version)
            throws IOException {
        String path = groupId.replace('.', '/') + "/" + artifactId + "/" + version + "/" + artifactId + "-" + version
                + ".jar";
        moduleConfig.addModuleUrl(new File(repository, path).toURI().toURL());
    }
}
